﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Sherwood.SignOn.Server.Models.Repositories
{
    public interface IUserAccountRepository
    {


        /// <summary>
        /// Returns a list of all accounts.
        /// This method should only be used for unit testing and/or maintainence scripts as it is unlikely
        /// to be efficient in production code.
        /// </summary>
        /// <returns></returns>
        IEnumerable<IUserAccount> GetAllAccounts();

        /// <summary>
        /// Deletes all user accounts.
        /// This method should only be used for unit testing in development enviroments.
        /// </summary>
        void DeleteAllAccounts();
      
        /// <summary>
        /// Provides user authentication using username and password
        /// </summary>
        /// <param name="username"></param>
        /// <param name="password"></param>
        /// <returns>UserAccount object if user is successfully authenticated. Null if user if authentication failed.</returns>
        IUserAccount AuthenticateUser(string username, string password);

        /// <summary>
        /// Get user account object for the specified userAccountId
        /// </summary>
        /// <param name="userAccountId"></param>
        /// <returns>Returns IUserAccount object if found, otherwise null.</returns>
        IUserAccount GetUserAccount(Guid userAccountId);


        /// <summary>
        /// Returns the first user account with the specified email address.
        /// </summary>
        /// <param name="email"></param>
        /// <returns></returns>
        IUserAccount GetUserAccountByEmail(string email);

        /// <summary>
        /// Returns the first user account with the specified email address.
        /// </summary>
        /// <param name="email"></param>
        /// <returns></returns>
        List<IUserAccount> GetAllUserAccountsByEmail(string email);

        /// <summary>
        /// Returns the first user account with the specified username.
        /// </summary>
        /// <param name="email"></param>
        /// <returns></returns>
        IUserAccount GetUserAccountByUsername(string username);

        /// <summary>
        /// Returns user accounts the match the search input
        /// </summary>
        /// <param name="search"></param>
        /// <returns></returns>
        IEnumerable<IUserAccount> GetUserAccounts(string search);


        /// <summary>
        /// Creates a new user account using the passed in parameters and
        /// returns the newly created account.
        /// </summary>
        /// <param name="parameters"></param>
        /// <returns>New account</returns>
        IUserAccount CreateUserAccount(CreateUserAccountParams parameters);


        /// <summary>
        /// Indicates whether it is ok to register a user with the provided
        /// parameters with an email address that already exists for another
        /// user.
        /// </summary>
        /// <param name="parameters"></param>
        /// <returns></returns>
        bool AllowDuplicateEmailAddress(CreateUserAccountParams parameters);

        /// <summary>
        /// Returns a user account that matches both username and email.
        /// </summary>
        /// <param name="userName"></param>
        /// <param name="email"></param>
        /// <returns>IUserAccount object or null if not found</returns>
        IUserAccount GetUserAccountByUsernameAndEmail(string userName, string email);

        /// <summary>
        /// Returns a user account that matches both username and email (if both are non null)
        /// or either username or email (if only one is non null)
        /// </summary>
        /// <param name="userName"></param>
        /// <param name="email"></param>
        /// <returns></returns>
        IUserAccount GetUserAccountByUsernameOrEmail(string userName, string email);

        /// <summary>
        /// Modifies an existing user account using the passed in parameters and
        /// returns the account.
        /// This method should not change username, password or email address as these
        /// changes require verification.
        /// </summary>
        /// <param name="parameters"></param>
        /// <returns>Modified account</returns>
        IUserAccount ModifyUserAccount(CreateUserAccountParams createAccountParams);

        /// <summary>
        /// Deletes the useracount with the specified id.
        /// </summary>
        /// <param name="userAccountId"></param>
        /// <returns></returns>
        bool DeleteUserAccount(Guid userAccountId);

    }

    public struct CreateUserAccountParams
    {
        public Guid UserAccountId { get; set; }
        public string Country { get; set; }
        public string CultureName1 { get; set; }
        public string CultureName2 { get; set; }
        public string CultureName3 { get; set; }
        public DateTime? DateOfBirth { get; set; }
        public string Email { get; set; }
        public string Mobile { get; set; }
        public string FirstName { get; set; }
        public Gender Gender { get; set; }
        public bool IsEnabled { get; set; }
        public string LastName { get; set; }
        public string RequestedUrl { get; set; }
        public string UserName { get; set; }
        public string Password { get; set; }
        public VerificationStatus VerificationStatus { get; set; }
    }
}
